package com.javasm.utils;


import com.javasm.common.Parameter;
import com.javasm.error.ExceptionEnum;
import com.javasm.error.JavasmException;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @className: JWTUtil
 * @description
 * @author: gfs
 * @date: 2024/7/13 10:42
 * @version: 0.1
 * @since : jdk11
 */
public class JWTUtil {

    //token加密的密钥
    private static final String keystr = "tumVg8G+G3LGnNmB5ZT2DqdJvgoKZZI1un7HDSiU4mo=";

    private static final String UID = "javasm";
    //设置登录Token过期时间,15天
    private static final Integer expTime = 1000 * 60 * 60 * 24 * 15;
    private static final Integer expEmailTime = 1000 * 60 * 10;

    public static final String Admin_Token = "javasm_token";

    //生成密钥,只需要生成一次就可以了,不需要反复调用
    private static void generateKey() {
        //指定key的算法
        SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256);
        //生成密钥 import io.jsonwebtoken.io.Encoders;
        String encode = Encoders.BASE64.encode(key.getEncoded());
        System.out.println(encode);
    }
    //email加密
    public static String generateEmail(String email){
        return baseGenerate(email,expEmailTime);
    }


    //加密
    public static String generate(Long uid) {
        //校验参数
        Parameter.check(uid);
        return generate(uid.toString());
    }

    public static String generate(Integer uid) {
        //校验参数
        Parameter.check(uid);
        return generate(uid.toString());
    }

    public static String generate(String uid) {
        return baseGenerate(uid,expTime);
    }
    private static String baseGenerate(String str,Integer exp){
        //校验参数
        Parameter.check(str);
        Map<String, Object> map = new HashMap<>();
        map.put(UID, str);
        //记录一个时间戳,让token能失效
        //记录一下,当前的token是哪个时间生成的
        Date time = new Date();
        //设置过期时间
        Date lastTime = new Date(time.getTime() + exp);
        //生成一个key
        SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(keystr));
        String token = Jwts.builder()
                .setClaims(map)//自定义签名
                .setIssuedAt(time)//标准签名
                .setExpiration(lastTime)//过期时间
                .signWith(key)//指定签名的密钥
                .compact();
        return token;
    }


    //解密
    public static String parse(String token) {

        SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(keystr));
        try {
            Jws<Claims> jws = Jwts.parserBuilder()
                    .setSigningKey(key)//设置签名,设置密钥,密码
                    .build()
                    .parseClaimsJws(token);
            Claims body = jws.getBody();
            String uid = body.get(UID, String.class);
            return uid;
        } catch (Exception e) {
            throw new JavasmException(ExceptionEnum.TokenExpError);
        }
    }

    public static void main(String[] args) {

        String token = JWTUtil.generate("1000");
        System.out.println(token);
//        String token = "eyJhbGciOiJIUzI1NiJ9.eyJqYXZhc20iOiIxMDAwIiwiaWF0IjoxNzIwODQyMDE2LCJleHAiOjE3MjA4NDIwMTd9.3SAz7BruwEy5u4QEFrVlF6QecycbicOvZMoyLoibJ3w";
//        String uid = JWTUtil.parse(token);

    }
}
